#include "MarsPrecompile.h"
#include "MarsMeshCube.h"
#include "MarsInputLayout.h"
#include "MarsVertexData.h"

typedef struct
{
	XMFLOAT3 Pos;
	XMFLOAT2 TexCoord;
	XMFLOAT3 Normal;
} Vertex;

bool MeshCube::Load()
{
	InputLayout* pInputLayout = new InputLayout();
	pInputLayout->AddElement( "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 );
	pInputLayout->AddElement( "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, sizeof(XMFLOAT3), D3D11_INPUT_PER_VERTEX_DATA, 0 );
	pInputLayout->AddElement( "NORMAL", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, sizeof(XMFLOAT3) + sizeof(XMFLOAT2), D3D11_INPUT_PER_VERTEX_DATA, 0 );

	Vertex* pVertices = new Vertex[ 24 ];

	Vertex vertices[] =
	{
		{ XMFLOAT3( -1.0f,  1.0f, -1.0f ), XMFLOAT2( 0.0f, 0.0f ), XMFLOAT3( 0.0f, 0.0f, 0.0f ) },
		{ XMFLOAT3(  1.0f,  1.0f, -1.0f ), XMFLOAT2( 1.0f, 0.0f ), XMFLOAT3( 0.0f, 0.0f, 0.0f ) },
		{ XMFLOAT3(  1.0f,  1.0f,  1.0f ), XMFLOAT2( 1.0f, 1.0f ), XMFLOAT3( 0.0f, 0.0f, 0.0f ) },
		{ XMFLOAT3( -1.0f,  1.0f,  1.0f ), XMFLOAT2( 0.0f, 1.0f ), XMFLOAT3( 0.0f, 0.0f, 0.0f ) },

		{ XMFLOAT3( -1.0f, -1.0f, -1.0f ), XMFLOAT2( 0.0f, 0.0f ), XMFLOAT3( 0.0f, 0.0f, 0.0f ) },
		{ XMFLOAT3(  1.0f, -1.0f, -1.0f ), XMFLOAT2( 1.0f, 0.0f ), XMFLOAT3( 0.0f, 0.0f, 0.0f ) },
		{ XMFLOAT3(  1.0f, -1.0f,  1.0f ), XMFLOAT2( 1.0f, 1.0f ), XMFLOAT3( 0.0f, 0.0f, 0.0f ) },
		{ XMFLOAT3( -1.0f, -1.0f,  1.0f ), XMFLOAT2( 0.0f, 1.0f ), XMFLOAT3( 0.0f, 0.0f, 0.0f ) },

		{ XMFLOAT3( -1.0f, -1.0f,  1.0f ), XMFLOAT2( 0.0f, 0.0f ), XMFLOAT3( 0.0f, 0.0f, 0.0f ) },
		{ XMFLOAT3( -1.0f, -1.0f, -1.0f ), XMFLOAT2( 1.0f, 0.0f ), XMFLOAT3( 0.0f, 0.0f, 0.0f ) },
		{ XMFLOAT3( -1.0f,  1.0f, -1.0f ), XMFLOAT2( 1.0f, 1.0f ), XMFLOAT3( 0.0f, 0.0f, 0.0f ) },
		{ XMFLOAT3( -1.0f,  1.0f,  1.0f ), XMFLOAT2( 0.0f, 1.0f ), XMFLOAT3( 0.0f, 0.0f, 0.0f ) },

		{ XMFLOAT3(  1.0f, -1.0f,  1.0f ), XMFLOAT2( 0.0f, 0.0f ), XMFLOAT3( 0.0f, 0.0f, 0.0f ) },
		{ XMFLOAT3(  1.0f, -1.0f, -1.0f ), XMFLOAT2( 1.0f, 0.0f ), XMFLOAT3( 0.0f, 0.0f, 0.0f ) },
		{ XMFLOAT3(  1.0f,  1.0f, -1.0f ), XMFLOAT2( 1.0f, 1.0f ), XMFLOAT3( 0.0f, 0.0f, 0.0f ) },
		{ XMFLOAT3(  1.0f,  1.0f,  1.0f ), XMFLOAT2( 0.0f, 1.0f ), XMFLOAT3( 0.0f, 0.0f, 0.0f ) },

		{ XMFLOAT3( -1.0f, -1.0f, -1.0f ), XMFLOAT2( 0.0f, 0.0f ), XMFLOAT3( 0.0f, 0.0f, 0.0f ) },
		{ XMFLOAT3(  1.0f, -1.0f, -1.0f ), XMFLOAT2( 1.0f, 0.0f ), XMFLOAT3( 0.0f, 0.0f, 0.0f ) },
		{ XMFLOAT3(  1.0f,  1.0f, -1.0f ), XMFLOAT2( 1.0f, 1.0f ), XMFLOAT3( 0.0f, 0.0f, 0.0f ) },
		{ XMFLOAT3( -1.0f,  1.0f, -1.0f ), XMFLOAT2( 0.0f, 1.0f ), XMFLOAT3( 0.0f, 0.0f, 0.0f ) },

		{ XMFLOAT3( -1.0f, -1.0f,  1.0f ), XMFLOAT2( 0.0f, 0.0f ), XMFLOAT3( 0.0f, 0.0f, 0.0f ) },
		{ XMFLOAT3(  1.0f, -1.0f,  1.0f ), XMFLOAT2( 1.0f, 0.0f ), XMFLOAT3( 0.0f, 0.0f, 0.0f ) },
		{ XMFLOAT3(  1.0f,  1.0f,  1.0f ), XMFLOAT2( 1.0f, 1.0f ), XMFLOAT3( 0.0f, 0.0f, 0.0f ) },
		{ XMFLOAT3( -1.0f,  1.0f,  1.0f ), XMFLOAT2( 0.0f, 1.0f ), XMFLOAT3( 0.0f, 0.0f, 0.0f ) },
	};

	uint16* pIndices = new uint16[ 36 ];
	uint16 indices[] =
	{
		3,   1,  0,  2,  1,  3,
		6,   4,  5,  7,  4,  6,
		11,  9,  8, 10,  9, 11,
		14, 12, 13, 15, 12, 14,
		19, 17, 16, 18, 17, 19,
		22, 20, 21, 23, 20, 22
	};

	MARS_MEMCPY( pIndices, indices, sizeof( indices ) );

 	for ( int i = 0; i < 12; ++i )
 	{
 		uint16 i0 = indices[ i * 3 + 0 ];
 		uint16 i1 = indices[ i * 3 + 1 ];
 		uint16 i2 = indices[ i * 3 + 2 ];
 
 		XMVECTOR v0 = XMLoadFloat3( &vertices[ i0 ].Pos );
 		XMVECTOR v1 = XMLoadFloat3( &vertices[ i1 ].Pos );
 		XMVECTOR v2 = XMLoadFloat3( &vertices[ i2 ].Pos );
 
 		XMVECTOR n0 = XMLoadFloat3( &vertices[ i0 ].Normal );
 		XMVECTOR n1 = XMLoadFloat3( &vertices[ i1 ].Normal );
 		XMVECTOR n2 = XMLoadFloat3( &vertices[ i2 ].Normal );
 
 		XMVECTOR v10 = v1 - v0;
 		XMVECTOR v20 = v2 - v0;
 
 		XMVECTOR normal = XMVector3Cross( v10, v20 );
 
 		n0 += normal;
 		n1 += normal;
 		n2 += normal;
 
 		XMStoreFloat3( &vertices[ i0 ].Normal, n0 );
 		XMStoreFloat3( &vertices[ i1 ].Normal, n1 );
 		XMStoreFloat3( &vertices[ i2 ].Normal, n2 );
 	}

	for ( int i = 0; i < 24; ++i )
	{
		XMVECTOR n = XMLoadFloat3( &vertices[ i ].Pos );
		n = XMVector3Normalize( n );
		XMStoreFloat3( &vertices[ i ].Normal, n );
	}

	MARS_MEMCPY( pVertices, vertices, sizeof( vertices ) );

	m_pVertexData = new VertexData( pInputLayout, ( uint8* ) pVertices, sizeof( Vertex ) * 24, ( uint8* ) pIndices, sizeof( indices ), VertexData::IBF_UInt16 );
	m_eTopology = D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST;

	m_iVertexCount = 36;
	m_iStride = sizeof( Vertex );
	m_iOffset = 0;

	return true;
}
